<?php

class Workset_Model_Observer_TreeNodeUpdater extends Workset_Model_Observer_Abstract {

	protected $_objectField = null;

	protected $_parent = null;

	function __construct($field = null) {
		if (null !== $field) {
			$this->setObjectField($field);
		}
	}

	function setObjectField($field) {
		$this->_objectField = (string)$field;
	}

	protected function _incrementNodesCount($subject) {
		if (isset($subject[$this->_objectField])) {
			$subject[$this->_objectField] += 1;
			$subject->save();
		} else {
			throw new Workset_Model_Exception('Undefined field "'.$this->_objectField.'" in subject');
		}
	}

	protected function _decrementNodesCount($subject) {
		if (isset($subject[$this->_objectField]) && $subject[$this->_objectField] > 0) {
			$subject[$this->_objectField] -= 1;
			$subject->save();
		} else {
			throw new Workset_Model_Exception('Undefined field "'.$this->_objectField.'" in subject');
		}
	}

	function beforeSave(Workset_Model_Subject_Interface $subject, $data = null) {
		$this->_parent = null;

		if ($subject instanceof Workset_Model_Object_TreeNode_Interface
			&&
			$subject instanceof Workset_Model_Object_Abstract)
		{
			if ($subject->getId() == 0 && $subject->hasParent()) {
				$this->_parent = $subject->getParent();
			}
		}
	}

	function afterSave(Workset_Model_Subject_Interface $subject, $data = null) {
		if (null !== $this->_parent) {
			$this->_incrementNodesCount($this->_parent);
		}

		$this->_parent = null;
	}

	function beforeDelete(Workset_Model_Subject_Interface $subject, $data = null) {
		$this->_parent = null;

		if ($subject instanceof Workset_Model_Object_TreeNode_Interface
			&&
			$subject instanceof Workset_Model_Object_Abstract)
		{
			if ($subject->hasParent()) {
				$this->_parent = $subject->getParent();
			}
		}
	}

	function afterDelete(Workset_Model_Subject_Interface $subject, $data = null) {
		if (null !== $this->_parent) {
			$this->_decrementNodesCount($this->_parent);
		}

		$this->_parent = null;
	}

}